package txproc

// 主要的存储数据结构是 map
// 主要用于每次的搜索结果，后续配合内存redis去检索
// 保存下来的结果用于后续的 长文档检索/存储

import (
	"fmt"
	"sync"
)

var (
	// FilterResult is the result for the high frequency memos
	filterResult = make(map[string]int)
	mu           sync.RWMutex // set the mutex lock for the filter map
)

// Words 用于保存最终的结果
type Words struct {
	linkWord string
	next     *Words
}

// AddWord 添加word
func AddWord(origin *Words, newOne *Words) {
	for origin.next != nil {
		origin = origin.next
	}
	origin.next = newOne
}

// PrintWords 将现有的词语打印
func PrintWords(memosWords []*Words) {
	for _, item := range memosWords {
		tail := item
		for tail.next != nil {
			fmt.Print(tail.linkWord)
			tail = tail.next
		}
	}
}

// GetHotWordsFromMemo 这个方法是主要处理梗的方法
// 每次处理一批获取到的数据
func GetHotWordsFromMemo(memos []string) {
	for i := 0; i < len(memos)-1; i++ {
		for j := i + 1; j < len(memos); j++ {
			FindSameWords(memos[i], memos[j])
		}
	}

	// 获得高频词汇的结果
	result := GetFilterResult()
	fmt.Println("result is ", result)
	// memoWords := []*Words{}
	// for k, v := range result {
	// 	theWord := &Words{}
	// 	theWord.linkWord = k

	// 	AddWord(memoWords[v], theWord)
	// 	fmt.Println("memowords", memoWords[v])
	// }

	// PrintWords(memoWords[:1])
}

// FindSameWords 将重复的词语提取出来
// 目前这种方式是暴力破解法，时间复杂度较高
// TODO:
// 优化相同词语提取的算法
func FindSameWords(str1 string, str2 string) {
	// 算法逻辑：将两个字符串中的字符逐个比较，将将重复的字符提取出来
	// 第1版算法，现将重复第所有字符都提取出来即可
	// 使用map 内存里面进行处理
	// ！！！需要注意：
	// 因为存储中文字符串，中文字符的大小大于一个字节，因此不能使用byte而是使用rune类型
	sameMap := make(map[rune]int)
	wordA := []rune(str1)
	wordB := []rune(str2)
	for _, wA := range wordA {
		for _, wB := range wordB {
			if wA == wB {
				if _, ok := sameMap[wA]; ok {
					sameMap[wA]++
				} else {
					sameMap[wA] = 1
				}

			}
		}
	}

	// 找到该词语然后完成拼接
	// 找到该单词，查看该单词是否大于1即可
	var sameWord []rune
	for _, c := range wordA {
		if sameMap[c] > 0 {
			sameWord = append(sameWord, c)
		}
	}

	if len(sameWord) > 0 {
		if _, ok := filterResult[string(sameWord)]; ok {
			filterResult[string(sameWord)]++
		} else {
			filterResult[string(sameWord)] = 1
		}
	}
}

// GetFilterResult get the inner FilterResult
func GetFilterResult() map[string]int {
	return filterResult
}
